<?php
	header('Access-Control-Allow-Origin: *');
	require('FileMakerDB.php');
	
    class Server{
    	
		private $request=NULL;
		
		/* response sarà così strutturata:
		 * response['status']: indica se la richiesta è andata a buon fine
		 * response['content']: la risposta in base alla richiesta, oppure un messaggio di errore
		 * */
		private $response=array();
		
    	public function listen(){
    		//non c'è nessuna richiesta
    		if(!isset($_POST['request'])){
    			$this->response['status']="error";
				$this->response['content']="Nessuna richiesta specificata.";
    		}
			//richiesta presente
			else{
				//decodifica la richiesta
				$this->request=$this->decompress($_POST['request']);
				
				//decodifica fallita
				if($this->request == NULL){
					$this->response['status']="error";
					$this->response['content']="Impossibile leggere la richiesta: formato corrotto.";
				}
				
				//decodifica riuscita
				else{
					$this->exitIfMissing(array('operation'));
					
					//se è una richiesta di ping, esegue subito senza fare altro
					if($this->request['operation'] == "ping"){
						$this->ping();
						exit;
					}
					
					else{
						$this->exitIfMissing(array('username','password'));
						
						//esegui la connessione al database FileMaker
						$database=FileMakerDB::getInstance();
						$this->response=$database->connect($this->request['username'],$this->request['password']);
						
						//connessione al database riuscita
						if($this->response['status']=="ok"){		
							switch ($this->request['operation']) {
								case 'authenticate':
									//non ripetiamo il controllo perchè abbiamo già controllato l'esistenza dei campi necessari
									$this->response=$database->getAuthenticationToken($this->request['username'],$this->request['password']);
									break;
								case 'get_table':
									$this->exitIfMissing(array('tableName'));
									$this->response=$database->getTable($this->request['tableName']);
									break;
								case 'get_record':
									$this->exitIfMissing(array('tableName','id'));
									$this->response=$database->getRecord($this->request['tableName'],$this->request['id']);
									break;
								case 'save_record':
									$this->exitIfMissing(array('tableName','fields'));
									$this->response=$database->saveRecord($this->request['tableName'],$this->request['fields']);
									break;
								case 'save_multiple_records':
									$this->exitIfMissing(array('recordsdata'));
									$this->response=$database->saveMultipleRecords($this->request['recordsData']);
									break;
								case 'update_record':
									$this->exitIfMissing(array('tableName','id','fields'));
									$this->response=$database->updateRecord($this->request['tableName'],$this->request['id'],$this->request['fields']);
									break;
								case 'update_multiple_records':
									$this->exitIfMissing(array('recordsData'));
									$this->response=$database->updateMultipleRecords($this->request['recordsData']);
									break;
								case 'delete_record':
									$this->exitIfMissing(array('tableName','id'));
									$this->response=$database->deleteRecord($this->request['tableName'],$this->request['id']);
									break;
								case 'delete_multiple_records':
									$this->exitIfMissing(array('recordsData'));
									$this->response=$database->deleteMultipleRecords($this->request['recordsData']);
									break;
								case 'get_changes_table':
									$this->exitIfMissing(array('version'));
									$this->response=$database->getChangesTable($this->request['version']);
									break;
								case 'get_db':
									$this->response=$database->getEntireDB();
									break;
								
								default:
									$this->response['status']="error";
									$this->response['content']="Operazione specificata non valida.";
									break;
							}
						}
					}
				}
				
			}
			$this->echoResponse();
    	}
		
		private function ping(){
			echo "{}";
		}
		
		/* Elabora l'array associativo dato in input per essere spedito al client.
		 * Esegue la conversione in stringa JSON e la comprime per salvare spazio*/
		private function compress($var){
			return json_encode($var);
		}
		
		/* Elabora la stringa proveniente dal client per essere interpretata dal server.
		 * Decomprime la stringa e la converte in un array associativo seguendo lo schema JSON*/
		private function decompress($string){
			//$string='{"operation": "authenticate","username":"lol", "password":"manol"}';
			return get_object_vars(json_decode($string));
		}
		private function echoResponse(){
			echo $this->compress($this->response);
		}
		
		/* controlla che sul'array associativo $request siano presenti gli argomenti
		 * indicati nell'array $arguments. Se uno dovesse mancare, termina il programma*/
		private function exitIfMissing($arguments=array()){
			
			foreach($arguments as $arg){
				if(!isset($this->request[$arg]) || $this->request[$arg]=="" || $this->request[$arg]==null){
					$this->response['status']="error";
					$this->response['content']="Parameter $arg not specified.";
					$this->echoResponse();
					exit;
				}
				
				
			
			}
		}
		
	}
?>
